package code.example.base.gc.gc1;

import code.example.base.gc.Person;
import code.example.tool.LogFactory;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

/**
 *   java -Xms512m -Xmx512m -cp ./lib/*:*.jar -XX:+PrintGCDetails -XX:+PrintHeapAtGC code.example.base.gc.gc1.TriggerGC1
 *
 *   输出gc:
 {Heap before GC invocations=1 (full 0):
 PSYoungGen      total 153088K, used 131584K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 131584K, 100% used [0x00000000f5580000,0x00000000fd600000,0x00000000fd600000)
 from space 21504K, 0% used [0x00000000feb00000,0x00000000feb00000,0x0000000100000000)
 to   space 21504K, 0% used [0x00000000fd600000,0x00000000fd600000,0x00000000feb00000)
 ParOldGen       total 349696K, used 0K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 0% used [0x00000000e0000000,0x00000000e0000000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 [GC (Allocation Failure) [PSYoungGen: 131584K->21488K(153088K)] 131584K->61936K(502784K), 0.4128813 secs] [Times: user=3.16 sys=0.08, real=0.41 secs]
 Heap after GC invocations=1 (full 0):
 PSYoungGen      total 153088K, used 21488K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 131584K, 0% used [0x00000000f5580000,0x00000000f5580000,0x00000000fd600000)
 from space 21504K, 99% used [0x00000000fd600000,0x00000000feafc010,0x00000000feb00000)
 to   space 21504K, 0% used [0x00000000feb00000,0x00000000feb00000,0x0000000100000000)
 ParOldGen       total 349696K, used 40448K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 11% used [0x00000000e0000000,0x00000000e2780000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 }
 {Heap before GC invocations=2 (full 0):
 PSYoungGen      total 153088K, used 153072K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 131584K, 100% used [0x00000000f5580000,0x00000000fd600000,0x00000000fd600000)
 from space 21504K, 99% used [0x00000000fd600000,0x00000000feafc010,0x00000000feb00000)
 to   space 21504K, 0% used [0x00000000feb00000,0x00000000feb00000,0x0000000100000000)
 ParOldGen       total 349696K, used 40448K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 11% used [0x00000000e0000000,0x00000000e2780000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 [GC (Allocation Failure) [PSYoungGen: 153072K->21504K(153088K)] 193520K->168344K(502784K), 0.8606153 secs] [Times: user=6.76 sys=0.11, real=0.86 secs]
 Heap after GC invocations=2 (full 0):
 PSYoungGen      total 153088K, used 21504K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 131584K, 0% used [0x00000000f5580000,0x00000000f5580000,0x00000000fd600000)
 from space 21504K, 100% used [0x00000000feb00000,0x0000000100000000,0x0000000100000000)
 to   space 21504K, 0% used [0x00000000fd600000,0x00000000fd600000,0x00000000feb00000)
 ParOldGen       total 349696K, used 146840K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 41% used [0x00000000e0000000,0x00000000e8f66000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 }
 场景:LinkedList 里不断的添加元素,最终 内存异常,jvm退出..

 说明了：
           jvm 数据放到eden 中，如果满了 触发 minor gc
             第一次GC:把eden中引用的放到 其中一个survivor中（from 或 to），清空eden ,如果survivor中放不下，则放到  OLD 中。
                      GC 之后：eden 0 ,survivor 一个有数据，一个没有数据，old :可能用，可能没有。
           jvm继续执行，还是把数据放到eden中，当eden 满了，再次触发minor gc
             第二次GC: 把有数据 eden +有数据的survivor ==》另一个survivor中，存不下的==》old

         LinkedList中元素越来越多,gc 回收时间越来越长,最终导至内存溢出,JVM报错.
                  Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
                   这个异常是说:GC 花了98%的时间,回收了不到2%的内存,说明了:老年代的对象都是有效的,即回收不了了.

 Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
 {Heap before GC invocations=51 (full 47):
 PSYoungGen      total 153088K, used 131584K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 131584K, 100% used [0x00000000f5580000,0x00000000fd600000,0x00000000fd600000)
 from space 21504K, 0% used [0x00000000feb00000,0x00000000feb00000,0x0000000100000000)
 to   space 21504K, 0% used [0x00000000fd600000,0x00000000fd600000,0x00000000feb00000)
 ParOldGen       total 349696K, used 349250K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 99% used [0x00000000e0000000,0x00000000f5510a98,0x00000000f5580000)
 Metaspace       used 3000K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 331K, capacity 386K, committed 512K, reserved 1048576K
 [Full GC (Ergonomics) [PSYoungGen: 131584K->0K(153088K)] [ParOldGen: 349250K->291K(349696K)] 480834K->291K(502784K), [Metaspace: 3000K->3000K(1056768K)], 0.0085664 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
 Heap after GC invocations=51 (full 47):
 PSYoungGen      total 153088K, used 0K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 131584K, 0% used [0x00000000f5580000,0x00000000f5580000,0x00000000fd600000)
 from space 21504K, 0% used [0x00000000feb00000,0x00000000feb00000,0x0000000100000000)
 to   space 21504K, 0% used [0x00000000fd600000,0x00000000fd600000,0x00000000feb00000)
 ParOldGen       total 349696K, used 291K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 0% used [0x00000000e0000000,0x00000000e0048d00,0x00000000f5580000)
 Metaspace       used 3000K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 331K, capacity 386K, committed 512K, reserved 1048576K
 }
 at java.util.LinkedList.linkLast(LinkedList.java:142)
 at java.util.LinkedList.add(LinkedList.java:338)
 at java.util.LinkedList.offer(LinkedList.java:696)
 at code.example.base.gc.gc1.TriggerGC1.test(TriggerGC1.java:81)
 at code.example.base.gc.gc1.TriggerGC1.main(TriggerGC1.java:90)
 Heap
 PSYoungGen      total 153088K, used 2719K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 131584K, 2% used [0x00000000f5580000,0x00000000f5827de8,0x00000000fd600000)
 from space 21504K, 0% used [0x00000000feb00000,0x00000000feb00000,0x0000000100000000)
 to   space 21504K, 0% used [0x00000000fd600000,0x00000000fd600000,0x00000000feb00000)
 ParOldGen       total 349696K, used 291K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 0% used [0x00000000e0000000,0x00000000e0048d00,0x00000000f5580000)
 Metaspace       used 3007K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 332K, capacity 386K, committed 512K, reserved 1048576K




 问题:为什么第一次GC时,就有对象存入了老年代??
 分析:是否是survivor中放不下,进入老年代的?
 测试:  survivor 与eden 设置为相同大小,survivor 应该 可以放下
 命令:
 java -Xms512m -Xmx512m -cp ./lib/*:*.jar -XX:InitialSurvivorRatio=2 -XX:+PrintGCDetails -XX:+PrintHeapAtGC code.example.base.gc.gc1.TriggerGC1
 结果:是因为survivor中放不下,进入老年代的.
 见日志:


 {Heap before GC invocations=1 (full 0):
 PSYoungGen      total 116736K, used 58880K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 58880K, 100% used [0x00000000f5580000,0x00000000f8f00000,0x00000000f8f00000)
 from space 57856K, 0% used [0x00000000fc780000,0x00000000fc780000,0x0000000100000000)
 to   space 57856K, 0% used [0x00000000f8f00000,0x00000000f8f00000,0x00000000fc780000)
 ParOldGen       total 349696K, used 0K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 0% used [0x00000000e0000000,0x00000000e0000000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 [GC (Allocation Failure) [PSYoungGen: 58880K->26320K(116736K)] 58880K->26328K(466432K), 0.1762751 secs] [Times: user=1.33 sys=0.02, real=0.17 secs]
 Heap after GC invocations=1 (full 0):
 PSYoungGen      total 116736K, used 26320K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 58880K, 0% used [0x00000000f5580000,0x00000000f5580000,0x00000000f8f00000)
 from space 57856K, 45% used [0x00000000f8f00000,0x00000000fa8b4010,0x00000000fc780000)
 to   space 57856K, 0% used [0x00000000fc780000,0x00000000fc780000,0x0000000100000000)
 ParOldGen       total 349696K, used 8K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 0% used [0x00000000e0000000,0x00000000e0002000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 }
 {Heap before GC invocations=2 (full 0):
 PSYoungGen      total 116736K, used 85200K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 58880K, 100% used [0x00000000f5580000,0x00000000f8f00000,0x00000000f8f00000)
 from space 57856K, 45% used [0x00000000f8f00000,0x00000000fa8b4010,0x00000000fc780000)
 to   space 57856K, 0% used [0x00000000fc780000,0x00000000fc780000,0x0000000100000000)
 ParOldGen       total 349696K, used 8K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 0% used [0x00000000e0000000,0x00000000e0002000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 [GC (Allocation Failure) [PSYoungGen: 85200K->55696K(116736K)] 85208K->55704K(466432K), 0.3595054 secs] [Times: user=2.82 sys=0.05, real=0.36 secs]
 Heap after GC invocations=2 (full 0):
 PSYoungGen      total 116736K, used 55696K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 58880K, 0% used [0x00000000f5580000,0x00000000f5580000,0x00000000f8f00000)
 from space 57856K, 96% used [0x00000000fc780000,0x00000000ffde4010,0x0000000100000000)
 to   space 57856K, 0% used [0x00000000f8f00000,0x00000000f8f00000,0x00000000fc780000)
 ParOldGen       total 349696K, used 8K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 0% used [0x00000000e0000000,0x00000000e0002000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 }
 {Heap before GC invocations=3 (full 0):
 PSYoungGen      total 116736K, used 114576K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 58880K, 100% used [0x00000000f5580000,0x00000000f8f00000,0x00000000f8f00000)
 from space 57856K, 96% used [0x00000000fc780000,0x00000000ffde4010,0x0000000100000000)
 to   space 57856K, 0% used [0x00000000f8f00000,0x00000000f8f00000,0x00000000fc780000)
 ParOldGen       total 349696K, used 8K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 0% used [0x00000000e0000000,0x00000000e0002000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 [GC (Allocation Failure) [PSYoungGen: 114576K->57840K(116736K)] 114584K->85184K(466432K), 0.5606742 secs] [Times: user=4.43 sys=0.05, real=0.56 secs]
 Heap after GC invocations=3 (full 0):
 PSYoungGen      total 116736K, used 57840K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
 eden space 58880K, 0% used [0x00000000f5580000,0x00000000f5580000,0x00000000f8f00000)
 from space 57856K, 99% used [0x00000000f8f00000,0x00000000fc77c010,0x00000000fc780000)
 to   space 57856K, 0% used [0x00000000fc780000,0x00000000fc780000,0x0000000100000000)
 ParOldGen       total 349696K, used 27344K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
 object space 349696K, 7% used [0x00000000e0000000,0x00000000e1ab4000,0x00000000f5580000)
 Metaspace       used 2975K, capacity 4490K, committed 4864K, reserved 1056768K
 class space    used 328K, capacity 386K, committed 512K, reserved 1048576K
 }


 */
public class TriggerGC1 {

    public void test(){
        Queue data = new LinkedList();
        for(int i=0;i<1000;i++){
            Person person = new Person();
            person.setName("TestK"+i);
            data.offer(person);
        }
        for(;;){
            for(int i=0;i<500;i++){
                data.poll();
            }
            for(int i=0;i<1000;i++){
                Person person = new Person();
                person.setName("TestK"+i);
                data.offer(person);
            }
          //  LogFactory.getLog().info("queue.size="+data.size());
            try {
                TimeUnit.MILLISECONDS.sleep(10);
            }catch (Exception e){}
        }
    }
    public static void main(String [] args){
        new TriggerGC1().test();
    }
}
